﻿
//是否使用brdf 贴图
//#define _MODEL_BRDF_QUALITY_HIGH_

#define _RES_WIN32_
//#define _RES_ANDROID_
//#define _RES_IOS_

using System.IO;
using UnityEditor;
using UnityEngine;
using Object = UnityEngine.Object;
using System.Collections.Generic;
using System.Text.RegularExpressions;


public class CommonSceneABConfig
{
    public static string WindowsBuildPath = "builds";
    public static string AndroidBuildPath = "builds_android";
    public static string IOSBuildPath = "builds_ios";

    //资源地址
    public static string APPLICATION_PATH = Application.dataPath + "/";

    //工程地址
    public static string PROJECT_PATH = APPLICATION_PATH.Substring(0, APPLICATION_PATH.Length - 7);

    public static string TargetPath = "{0}/../../GameClient_GamePlay/{1}/AssetBundles/world/playercreate/slg_scene";

    //AssetBundle打包的后缀名
    public static string SUFFIX = ".unity3d";

    //此处添加需要命名assetBundleName的资源后缀名,注意大小写。
    public static string[] Filtersuffix = new string[] {
        // ".prefab",//1
        // ".mat",
        // ".asset",
        // ".png",
        // ".jpg",//5
        // ".tga",
        // ".psd",//9
        // ".fbx",
        // ".shader",
        // ".anim",
        // ".controller",
        ".exr"
    };

    public static string[] DirName = new string[] {
        // "prefab",//1
        // "material",
        // "asset",
        // "texpng",
        // "texjpg",//5
        // "textga",
        // "texpsd",//9
        // "fbx",
        // "shader",
        // "anim",
        // "controller",
        "lightmap"
    };

    // public static Dictionary<string, string> suffixDirMap = new Dictionary<string, string>() {
    //     {  ".prefab","prefab"},
    //     { ".mat","material"},
    //     { ".png","texpng"},
    //     { ".asset", "asset"},
    //     { ".jpg","texjpg"},
    //     { ".tga","textga"},
    //     { ".fbx","fbx"},
    //     { ".anim","anim"},
    //     { ".controller","controller"}
    // };
}

public class HUBuildSceneBundle
{
    static private string m_ExportPath = string.Empty;

    static private string[] fullPaths = new string[0];

    static Dictionary<string, string> SuffixDirPathMap = new Dictionary<string, string>();

#if _MODEL_BRDF_QUALITY_HIGH_
	static string model_res_path = "model_res_high_quality";
    public static bool is_use_brdf_quality = true;
	public static string use_brdf_quality = "use BRDF HIGH Quality";
	static string quelity_end = "_high_quality";
#else
    static string model_res_path = "model_res";
    public static bool is_use_brdf_quality = false;
    public static string use_brdf_quality = "use SOSO Quality";
    static string quelity_end = "";
#endif

#if _RES_WIN32_
    public static string BuildsPath = "builds";
    public static string TargetType = "win32";
    public static BuildTarget BuildTargetOpt = BuildTarget.StandaloneWindows64;
#elif _RES_ANDROID_
	public static string BuildsPath = "builds_android";
	public static string TargetType = "android";
    public static BuildTarget BuildTargetOpt = BuildTarget.Android;
#elif _RES_IOS_
	public static string BuildsPath = "builds_ios";
	public static string TargetType = "ios";
    public static BuildTarget BuildTargetOpt = BuildTarget.iOS;
#endif


    [MenuItem("New AB Editor/Build Scene/Build For Windows")]
    public static void BuildSceneForWindows()
    {
        MakeSceneResourceAb("builds");
    }
    [MenuItem("New AB Editor/Build Scene/Build For Android")]
    public static void BuildSceneForAndroid()
    {
        MakeSceneResourceAb("builds_android");

    }
    [MenuItem("New AB Editor/Build Scene/Build For IOS")]
    public static void BuildSceneForIOS()
    {
        MakeSceneResourceAb("builds_ios");

    }

    [MenuItem("New AB Editor/TestSuffix")]
    public static void ShowAllSuffix()
    {
        string[] paths = GetSelectPaths();
        List<string> ret = new List<string>();

        for (int i = 0; i < paths.Length; i++)
        {
            string[] temps = paths[i].Split('.');
            if (temps.Length > 0)
            {
                string suffix = temps[temps.Length - 1];
                if (ret.Contains(suffix) == false)
                {
                    ret.Add(suffix);
                }
                if (suffix.EndsWith("psd") == true)
                {
                    Debug.Log(paths[i]);
                }
            }
        }

        string output = string.Empty;
        for (int i = 0; i < ret.Count; i++)
        {
            output += string.Format("suffix[{0}]:{1},", i, ret[i]);
        }

        Debug.Log(output);
    }

    /// <summary>
    /// 此处做不同平台兼容处理
    /// </summary>
    /// <param name="buildsPath"></param>
    public static void MakeSceneResourceAb(string buildsPath)
    {
        return;//暂时不打包光照图了
        string targetPath;
        BuildTarget targetBuild;
        if (buildsPath == "builds")
        {
            targetPath = string.Format(CommonSceneABConfig.TargetPath, Application.dataPath, CommonSceneABConfig.WindowsBuildPath);
            targetBuild = BuildTarget.StandaloneWindows64;
        }
        else if (buildsPath == "builds_android")
        {
            targetPath = string.Format(CommonSceneABConfig.TargetPath, Application.dataPath, CommonSceneABConfig.AndroidBuildPath);
            targetBuild = BuildTarget.Android;

        }
        else if (buildsPath == "builds_ios")
        {
            targetPath = string.Format(CommonSceneABConfig.TargetPath, Application.dataPath, CommonSceneABConfig.IOSBuildPath);
            targetBuild = BuildTarget.iOS;

        }
        else
        {
            Debug.LogErrorFormat("no this config in HUBuildSceneBundle,please check it");
            return;
        }

        //此处扩展目录
        fullPaths = new string[]
        {
            // "Assets" + "/scene_tools/create_scene/create_fight_scene/create_fight_scene.prefab",
            // "Assets" + "/scene_tools/create_scene/create_selectrole_scene/create_selectrole_scene.prefab",
            // "Assets" + "/scene_tools/create_scene/create_world_scene/create_world_scene.prefab",
            // "Assets" + "/scene_tools/create_scene/create_zergcity_scene/create_zergcity_scene.prefab",
            // "Assets" + "/scene_tools/create_scene/create_terran_scene/create_terran_scene.prefab",
            // "Assets" + "/scene_tools/create_scene/create_protoss_scene/create_protoss_scene.prefab",
            "Assets/scene_tools/create_scene/create_zergcity_scene",
            "Assets/scene_tools/create_scene/create_protoss_scene",
            "Assets/scene_tools/create_scene/create_terran_scene",
            "Assets/scene_tools/create_scene/create_world_scene",
        };

        OneKeyToMakeBundleImpl(targetPath, targetBuild/*, CommonSceneABConfig.suffixDirMap*/);
    }

    //[MenuItem("New AB Editor/Build AssetBundles")]
    /// <summary>
    /// 此处为真正的api
    /// </summary>
    /// <param name="targetPath"></param>
    /// <param name="targetBuild"></param>
    /// <param name="suffixDirMap"></param>
    public static void OneKeyToMakeBundleImpl(string targetPath, BuildTarget targetBuild/*,Dictionary<string,string> suffixDirMap*/)
    {
        //SetExportPath(string.Format("{0}/../../GameClient_GamePlay/{1}/AssetBundles/world/playercreate/slg_scene", Application.dataPath, BuildsPath));
        SetExportPath(targetPath);
        // SetFilterInfo(suffixDirMap);

        //string fullPath = GetSelectPath();
        if (fullPaths.Length == 0)
        {
            fullPaths = GetSelectPaths();

        }

        if (fullPaths.Length == 0)
        {
            if (EditorUtility.DisplayDialog("提示", "请至少选择一个目录或者文件", "ok"))
            {
                return;
            }
            return;
        }

        string messageStr = string.Empty;
        for (int i = 0; i < fullPaths.Length; i++)
        {
            messageStr += fullPaths[i] + "\r\n";
        }

        if (EditorUtility.DisplayDialog("制作AssetBundle路径确认", string.Format("你要制作AB包的来源为{0},输出目录为{1}", messageStr, m_ExportPath), "confirm", "cancel"))
        {
            string[] names = AssetDatabase.GetAllAssetBundleNames();
            if (names.Length != 0)
            {
                SetResourcesAssetBundleName(CommonSceneABConfig.APPLICATION_PATH, true);
            }

            // List<string> dependencies = GetDependenciesPath(fullPaths);
            List<string> dependencies = GetDependenciesByDirs(fullPaths);
            for (int i = 0; i < dependencies.Count; i++)
            {
                SetResourcesAssetBundleName(dependencies[i], false);
            }

            AssetBundleManifest abm = BuildPipeline.BuildAssetBundles(
             m_ExportPath,
            BuildAssetBundleOptions.ChunkBasedCompression |
             BuildAssetBundleOptions.DeterministicAssetBundle,
             targetBuild);
            for (int i = 0; i < dependencies.Count; i++)
            {
                SetResourcesAssetBundleName(dependencies[i], true);
            }
        }
    }

    //[MenuItem("New AB Editor/GetAllAssetBundleName")]
    /// <summary>
    /// 收集选中文件的AssetBundleName
    /// </summary>
    static void GetAllAssetBundleName()
    {

        string[] names = AssetDatabase.GetAllAssetBundleNames();

        foreach (var name in names)
        {
            Debug.Log(name);
        }

    }

    //[MenuItem("New AB Editor/ClearAssetBundleName")]
    /// <summary>
    /// 清除选中文件的AssetBundleName
    /// </summary>
    static void ClearResourcesAssetBundleName()
    {
        string[] fullPaths = GetSelectPaths();

        if (fullPaths.Length == 0)
        {
            if (EditorUtility.DisplayDialog("提示", "请至少选择一个目录或者文件", "ok"))
            {
                return;
            }
            return;
        }

        string messageStr = string.Empty;
        for (int i = 0; i < fullPaths.Length; i++)
        {
            messageStr += fullPaths[i] + "\r\n";
        }

        if (EditorUtility.DisplayDialog("清除AssetName名称确认", string.Format("你要清除AssetName的位置为{0}", messageStr), "confirm", "cancel"))
        {
            for (int i = 0; i < fullPaths.Length; i++)
            {
                SetResourcesAssetBundleName(fullPaths[i], true);
            }
            EditorUtility.ClearProgressBar();
            AssetDatabase.RemoveUnusedAssetBundleNames();
        }

    }

    /// <summary>
    /// 设置导出路径
    /// </summary>
    /// <param name="path"></param>
    public static void SetExportPath(string path)
    {
        //m_ExportPath = string.Format("{0}/../../GameClient_GamePlay/{1}/AssetBundles/model/spine_anim/", Application.dataPath, BuildsPath);
        m_ExportPath = path;

        if (Directory.Exists(m_ExportPath) == false)
        {
            Directory.CreateDirectory(m_ExportPath);
        }

    }

    [MenuItem("New AB Editor/Test Directory.GetFiles")]
    public static void TestDirectoryGetFiles()
    {
        string[] strs = new string[] {
            "Assets/scene_tools/create_scene/create_zergcity_scene",
            "Assets/scene_tools/create_scene/create_protoss_scene",
            "Assets/scene_tools/create_scene/create_terran_scene",
            "Assets/scene_tools/create_scene/create_world_scene",
        };
        GetDependenciesByDirs(strs);
    }

    /// <summary>
    /// 得到指定目录下的资源的依赖列表,目前只用来查找lightmap
    /// </summary>
    /// <param name="prefabPaths"></param>
    /// <returns></returns>

    public static List<string> GetDependenciesByDir(string dir)
    {
        var files = Directory.GetFiles(dir, "*.exr");
        var ret = new List<string>();
        Regex reg = new Regex("Light.*/.exr$");
        foreach (var item in files)
        {
            // Debug.Log(item);
            if (Regex.IsMatch(item, "Light.+exr$") == true)
            {
                // Debug.Log(item);
                // List<string> temp = GetDependenciesPath(item);
                ret.Add(item);
            }
        }

        return ret;
    }

    /// <summary>
    /// 得到一堆指定目录下的资源的依赖列表
    /// </summary>
    /// <param name="prefabPaths"></param>
    /// <returns></returns>
    public static List<string> GetDependenciesByDirs(string[] dirs)
    {
        List<string> ret = new List<string>();
        int count = 0;
        for (int i = 0; i < dirs.Length; i++)
        {
            List<string> temps = GetDependenciesByDir(dirs[i]);
            count += temps.Count;
            for (int j = 0; j < temps.Count; j++)
            {
                if (ret.Contains(temps[j]) == false)
                {
                    ret.Add(temps[j]);
                }
                // EditorUtility.DisplayProgressBar("收集依赖信息", "信息收集中。。。", 1f * i / dirs.Length);
            }
        }
        // Debug.LogFormat("Count:{0}",count);
        // EditorUtility.ClearProgressBar();
        return ret;
    }

    /// <summary>
    /// 得到指定prefab的依赖列表
    /// </summary>
    /// <param name="prefabPaths"></param>
    /// <returns></returns>
    public static List<string> GetDependenciesPath(string[] prefabPaths)
    {
        List<string> ret = new List<string>();
        for (int i = 0; i < prefabPaths.Length; i++)
        {
            List<string> temps = GetDependenciesPath(prefabPaths[i]);
            for (int j = 0; j < temps.Count; j++)
            {
                if (ret.Contains(temps[j]) == false)
                {
                    ret.Add(temps[j]);
                }
            }
            EditorUtility.DisplayProgressBar("收集依赖信息", "信息收集中。。。", 1f * i / prefabPaths.Length);
        }


        return ret;
    }

    /// <summary>
    /// 得到指定prefab的依赖列表
    /// </summary>
    /// <param name="prefabPath"></param>
    /// <returns></returns>
    public static List<string> GetDependenciesPath(string prefabPath)
    {
        //参数是数组，可以同时查找多个prefab
        //"Assets/scene_tools/create_scene/create_world_scene/create_world_scene.prefab"
        string[] paths = AssetDatabase.GetDependencies(prefabPath);
        List<string> ret = new List<string>();
        foreach (string path in paths)
        {
            //Debug.Log(path);
            if (ret.Contains(path) == false)
            {
                ret.Add(path);

            }
        }

        return ret;
    }

    // /// <summary>
    // /// 设置后缀名过滤表
    // /// </summary>
    // /// <param name="suffixDirMap"></param>
    // private static void SetFilterInfo(Dictionary<string, string> suffixDirMap)
    // {
    //     SuffixDirPathMap = suffixDirMap;
    // }

    /// <summary>
    /// 设置或清除文件的AssetBundleName
    /// </summary>
    /// <param name="fileInfo"></param>
    /// <param name="clear"></param>
    private static void SetFileAssetBundleName(FileInfo fileInfo, bool clear = false)
    {
        for (int i = 0; i < CommonSceneABConfig.Filtersuffix.Length; i++)
        {
            string suffix = CommonSceneABConfig.Filtersuffix[i];
            if (fileInfo.Name.EndsWith(suffix, true, null))
            {
                string path = fileInfo.FullName.Replace('\\',
                '/').Substring(CommonSceneABConfig.PROJECT_PATH.Length);
                var importer = AssetImporter.GetAtPath(path);
                if (importer)
                {
                    if (clear)
                    {
                        importer.assetBundleName = null;
                    }
                    else
                    {
                        string name = fileInfo.Name;
                        string dirName = CommonSceneABConfig.DirName[i];
                        importer.assetBundleName = dirName + "/" + name.Substring(0, name.LastIndexOf('.')) + CommonSceneABConfig.SUFFIX;
                    }
                }
            }
        }
    }

    /// <summary>
    /// 设置或清除资源的AssetBundleName
    /// </summary>
    /// <param name="fullPath"></param>
    /// <param name="clear"></param>
    static void SetResourcesAssetBundleName(string fullPath, bool clear)
    {
        if (Directory.Exists(fullPath))
        {
            DirectoryInfo dir = new DirectoryInfo(fullPath);

            var files = dir.GetFiles("*", SearchOption.AllDirectories);
            ;
            for (var i = 0; i < files.Length; ++i)
            {
                var fileInfo = files[i];
                if (fileInfo.Name.EndsWith(".meta") && clear == false)//添加标记的时候meta过滤掉
                {
                    continue;
                }
                if (clear == false)
                {
                    EditorUtility.DisplayProgressBar("设置AssetName名称", "正在设置AssetName名称中...",
                    1f * i / files.Length);
                }
                else
                {
                    EditorUtility.DisplayProgressBar("清除AssetName名称", "正在清除AssetName名称中...",
                                        1f * i / files.Length);
                }

                SetFileAssetBundleName(fileInfo, clear);
            }

        }
        else if (File.Exists(fullPath))
        {
            FileInfo fileInfo = new FileInfo(fullPath);

            SetFileAssetBundleName(fileInfo, clear);
        }

        if (clear == true)
        {
            AssetDatabase.RemoveUnusedAssetBundleNames();
        }

        EditorUtility.ClearProgressBar();
    }

    static string[] GetSelectPaths()
    {
        UnityEngine.Object[] SelectedAsset = Selection.GetFiltered(typeof(Object), SelectionMode.Unfiltered);
        //此处添加需要命名的资源后缀名,注意大小写。
        string[] paths = new string[SelectedAsset.Length];

        for (int i = 0; i < paths.Length; i++)
        {
            paths[i] = CommonSceneABConfig.PROJECT_PATH + AssetDatabase.GetAssetPath(SelectedAsset[i]);
        }

        return paths;
    }

    static string GetSelectPath()
    {
        UnityEngine.Object[] SelectedAsset = Selection.GetFiltered(typeof(Object), SelectionMode.Unfiltered);
        //此处添加需要命名的资源后缀名,注意大小写。
        if (!(SelectedAsset.Length == 1)) return string.Empty;

        string fullPath = CommonSceneABConfig.PROJECT_PATH + AssetDatabase.GetAssetPath(SelectedAsset[0]);
        return fullPath;
    }
}

